import { computed, defineComponent, PropType, ref, unref } from 'vue'
import './index.css'
import resizer from './resizer'

export interface ContextProps {
  minPercent: number
  defaultPercent: number
  split: string
}

/** 切割面板组件 */
export default defineComponent({
  name: 'SplitPane',
  components: { resizer },
  props: {
    splitSet: {
      type: Object as PropType<ContextProps>,
      require: true,
      default: null
    }
  },
  emits: ['resize'],
  setup(props, ctx) {
    const active = ref(false)
    const hasMoved = ref(false)
    const percent = ref(props.splitSet?.defaultPercent)
    const type = props.splitSet?.split === 'vertical' ? 'width' : 'height'
    const resizeType = props.splitSet?.split === 'vertical' ? 'left' : 'top'

    const leftClass = ref(['splitter-pane splitter-paneL', props.splitSet?.split])

    const rightClass = ref(['splitter-pane splitter-paneR', props.splitSet?.split])

    const cursor = computed(() => {
      return active.value
        ? props.splitSet?.split === 'vertical'
          ? { cursor: 'col-resize' }
          : { cursor: 'row-resize' }
        : { cursor: 'default' }
    })

    const onClick = (): void => {
      if (!hasMoved.value) {
        percent.value = 50
        ctx.emit('resize', percent.value)
      }
    }

    const onMouseDown = (): void => {
      active.value = true
      hasMoved.value = false
    }

    const onMouseUp = (): void => {
      active.value = false
    }

    const onMouseMove = (e: any): void => {
      if (e.buttons === 0 || e.which === 0) {
        active.value = false
      }

      if (active.value) {
        let offset = 0
        let target = e.currentTarget
        if (props.splitSet?.split === 'vertical') {
          while (target) {
            offset += target.offsetLeft
            target = target.offsetParent
          }
        } else {
          while (target) {
            offset += target.offsetTop
            target = target.offsetParent
          }
        }

        const currentPage = props.splitSet?.split === 'vertical' ? e.pageX : e.pageY
        const targetOffset =
          props.splitSet?.split === 'vertical'
            ? e.currentTarget.offsetWidth
            : e.currentTarget.offsetHeight
        const percents = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100

        if (percents > props.splitSet?.minPercent && percents < 100 - props.splitSet?.minPercent) {
          percent.value = percents
        }

        ctx.emit('resize', percent.value)

        hasMoved.value = true
      }
    }

    return () => (
      <>
        <div
          class="vue-splitter-container clearfix"
          style={unref(cursor)}
          onMouseup={() => onMouseUp()}
          onMousemove={() => onMouseMove(event)}
        >
          <div class={unref(leftClass)} style={{ [unref(type)]: unref(percent) + '%' }}>
            {ctx?.slots && ctx.slots.pageL && ctx.slots.pageL()}
          </div>
          <resizer
            style={`${unref([resizeType])}:${unref(percent)}%`}
            split={props.splitSet?.split}
            onMousedown={() => onMouseDown()}
            onClick={() => onClick()}
          ></resizer>
          <div class={unref(rightClass)} style={{ [unref(type)]: 100 - unref(percent) + '%' }}>
            {ctx?.slots && ctx.slots.pageR && ctx.slots.pageR()}
          </div>
          <div v-show={unref(active)} class="vue-splitter-container-mask"></div>
        </div>
      </>
    )
  }
})
